package com.github.dtkavin.bgq.graph_meta

import org.neo4j.driver.v1.{AuthTokens, GraphDatabase, Session}
import org.slf4j.{Logger, LoggerFactory}

/**
  * Function: Neo4J客户端工具类
  * #Author: john 
  * #Create: 2018 03 30 下午3:16 
  */

/**
  * hdfs仓库存储基本信息
  *
  * @param id          自然ｉｄ
  * @param path        　存储路径
  * @param liveCycle   　生命周期（单位为ｄａｙ）
  * @param monitor     　维护者
  * @param description 　表业务描述，用途描述
  * @param createTime  　
  * @param updateTime
  */
sealed abstract class Storage(id: Int, path: String, liveCycle: Int, monitor: String, description: String, createTime: String, updateTime: String)

/**
  * 依赖关系基本信息
  *
  * @param id          　自然ｉｄ
  * @param source      　来源
  * @param target      去向
  * @param description 　业务描述，使用描述
  * @param createTime
  * @param updateTime
  */
sealed abstract class Dependency(id: Int, source: String, target: String, description: String, createTime: String, updateTime: String)

/**
  * 原始日志
  *
  * @param id          自然ｉｄ
  * @param path        　存储路径
  * @param liveCycle   　生命周期（单位为ｄａｙ）
  * @param monitor     　维护者
  * @param timeZone    dt/hour［增量方式］
  * @param description 　表业务描述，用途描述
  * @param createTime  　
  * @param updateTime
  */
class OriginLog(id: Int, path: String, liveCycle: Int, monitor: String, timeZone: String, description: String, createTime: String, updateTime: String) extends Storage(id = id, path = path, liveCycle = liveCycle, monitor = monitor, description = description, createTime = createTime, updateTime = updateTime){}

/**
  * 仓库表
  *
  * @param id          自然ｉｄ
  * @param name        表名
  * @param category    　类型（Enter/Build）［录入/自动构建］
  * @param timeZone    　dt/hour［增量方式］
  * @param dbName      库名
  * @param liveCycle   　生命周期（单位为ｄａｙ）
  * @param monitor     　维护者
  * @param partitions  　表的分区，用分号分割,有序，如dt;pn;hour;et
  * @param path        　存储路径
  * @param level       　仓库分层（1-ods,2-dw）
  * @param description 　表业务描述，用途描述
  * @param createTime  　
  * @param updateTime
  */
case class WhsTable(id: Int, name: String, category: String, timeZone: String, dbName: String, liveCycle: Int, monitor: String, partitions: String, path: String, level: Int, description: String, createTime: String, updateTime: String) extends Storage(id = id, path = path, liveCycle = liveCycle, monitor = monitor, description = description, createTime = createTime, updateTime = updateTime)
//case class WhsTable()(id: Int)(name: String)(category: String)(timeZone: String)(dbName: String)(liveCycle: Int)(monitor: String)(partitions: String)(path: String)(level: Int)(description: String)(createTime: String)(updateTime: String) extends Storage(id = id, path = path, liveCycle = liveCycle, monitor = monitor, description = description, createTime = createTime, updateTime = updateTime){




/**
  * 仓库依赖关系
  *
  * @param id            　自然ｉｄ
  * @param sources_table 　来源表
  * @param target_table  去向表
  * @param sql           　处理逻辑的ｓｑｌ
  * @param description   　业务描述，使用描述
  * @param createTime
  * @param updateTime
  */
case class WhsRelationShip(id: Int, sources_table: String, target_table: String, sql: String, description: String, createTime: String, updateTime: String) extends Dependency(id = id, source = sources_table, target = target_table, description = description, createTime = createTime, updateTime = updateTime)

/**
  * Neo4j基本操作，不涉及业务
  */
class Neo4JUtils {
  protected lazy val log: Logger = LoggerFactory.getLogger(this.getClass)

  val ip = "10.10.16.16"
  val port = 7687
  val userName = "neo4j"
  val passwd = "root"

  /**
    * 无结果操作，有异常时退出
    *
    * @param fn 　session相关操作
    */
  protected def do2Unit(fn: Session => Unit): Unit = {
    val driver = try {
      GraphDatabase.driver(s"bolt://${ip}:${port}", AuthTokens.basic(s"${userName}", s"${passwd}"))
    } catch {
      case ex: Exception => {
        ex.printStackTrace()
        sys.exit(1)
      }
    }
    val session = try {
      driver.session()
    } catch {
      case ex: Exception => {
        ex.printStackTrace()
        sys.exit(2)
      }
    }

    try {
      fn(session)
    } catch {
      case ex: Exception => {
        ex.printStackTrace()
        sys.exit(3)
      }
    }
    finally {
      session.close()
      driver.close()
    }
  }

  /**
    * 返回ｌｉｓｔ的操作
    *
    * @param fn 　session相关操作
    * @tparam T 　
    * @return 　ｌｉｓｔ, 有异常时退出
    */
  protected def do2List[T](fn: Session => List[T]): List[T] = {
    val driver = try {
      GraphDatabase.driver(s"bolt://${ip}:${port}", AuthTokens.basic(s"${userName}", s"${passwd}"))
    } catch {
      case ex: Exception => {
        ex.printStackTrace()
        sys.exit(1)
      }
    }
    val session = try {
      driver.session()
    } catch {
      case ex: Exception => {
        ex.printStackTrace()
        sys.exit(2)
      }
    }

    try {
      fn(session)
    } catch {
      case ex: Exception => {
        ex.printStackTrace()
        sys.exit(3)
      }
    }
    finally {
      session.close()
      driver.close()
    }
  }


}
